#include <stdio.h>
#include <string.h>

#include <gtk/gtk.h>

#include "knots.h"
#include "appdata.h"
#include "interface.h"

#ifdef G_OS_WIN32
#include <windows.h>
#include <commdlg.h>
#endif

void drawKnot() {
  gtk_widget_queue_draw_area(drawingArea, 0, 0, drawingArea->allocation.width, drawingArea->allocation.height);
}

void newKnot(int width, int height) {
  int i, j;

  kwidth = width;
  kheight = height;

  for (i = 1; i < (kwidth - 1); i++) {
    for (j = 1; j < (kheight - 1); j++) {
      knot[arraypos(i, j)] = 40;
    }
  }

  for (j = 1; j < (kheight - 1); j++) {
    knot[arraypos(0, j)] = 39;
    knot[arraypos(kwidth - 1, j)] = 31;
  }

  for (i = 1; i < (kwidth - 1); i++) {
    knot[arraypos(i, 0)] = 13;
    knot[arraypos(i, kheight - 1)] = 37;
  }

  knot[arraypos(0, 0)] = 12;
  knot[arraypos(kwidth - 1, 0)] = 4;
  knot[arraypos(0, kheight - 1)] = 36;
  knot[arraypos(kwidth - 1, kheight - 1)] = 28;
}

void setTitle(char *newTitle) {
  char tmp[512];
  strcpy(tmp, "Knot 770 - ");
  strcat(tmp, newTitle);
  gtk_window_set_title(GTK_WINDOW(window), tmp);
}

void do_new() {
  gint result;
  GtkWidget *newDialog;

  int newWidth;
  int newHeight;

  newDialog = GTK_WIDGET(create_new_dialog());
  result = gtk_dialog_run (GTK_DIALOG (newDialog));

  switch (result) {
    case GTK_RESPONSE_OK:
      // do new knot
      is_dirty = FALSE;
      newWidth = gtk_range_get_value(GTK_RANGE(hscale1));
      newHeight = gtk_range_get_value(GTK_RANGE(hscale2));
      newKnot(newWidth, newHeight);
      gtk_widget_set_size_request(drawingArea, kwidth * TILEWIDTH, kheight * TILEHEIGHT);
      drawKnot();
      have_fname = FALSE;
      strcpy(fname, "");
      setTitle("");
      break;
    default:
      // dont do new
      break;
  }

  gtk_widget_destroy (newDialog);
}

void toggle_fullscreen() {
  is_fullscreen = !is_fullscreen;
  if (is_fullscreen) {
    gtk_window_fullscreen(GTK_WINDOW(window));
  }
  else {
    gtk_window_unfullscreen(GTK_WINDOW(window));
  }
}

int arraypos(int x, int y) {
  return (y * kwidth + x);
}

void open_file(char *filename) {
  FILE *fp;
  int i, c;
  int newWidth, newHeight;

  fp=fopen(filename, "r");

  // First ignore header
  for (i = 0; i < 16; i++) {
    c = fgetc (fp);
  }

  // Now get knot size
  c = fgetc(fp);
  newWidth = c;  // width byte
  c = fgetc(fp); // zero

  c = fgetc(fp);
  newHeight = c; // height byte
  c = fgetc(fp); // zero

  // Now get contents
  for (i = 0; i < (newWidth * newHeight); i++) {
    knot[i] = fgetc(fp);
  }

  fclose(fp);

  kwidth = newWidth;
  kheight = newHeight;
  gtk_widget_set_size_request(drawingArea, kwidth * TILEWIDTH, kheight * TILEHEIGHT);
  drawKnot();
  is_dirty = FALSE;
}

void do_open() {
  gboolean doLoad = FALSE;

#ifdef G_OS_WIN32
  OPENFILENAME ofn;
  char szFileName[MAX_PATH] = "";
#else
  GtkWidget *dialog;
#endif

#ifdef G_OS_WIN32
  ZeroMemory(&ofn, sizeof(ofn));
  ofn.lStructSize = sizeof(ofn);
  ofn.hwndOwner = NULL;
  ofn.lpstrFilter = "Knot Files (*.knt)\0*.knt\0All Files (*.*)\0*.*\0";
  ofn.lpstrFile = szFileName;
  ofn.nMaxFile = MAX_PATH;
  ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  ofn.lpstrDefExt = "knt";
  if (GetOpenFileName(&ofn)) {
    doLoad = TRUE;
    strcpy(fname, szFileName);
  }
#else
  dialog = gtk_file_chooser_dialog_new ("Open File",
				      GTK_WINDOW(window),
				      GTK_FILE_CHOOSER_ACTION_OPEN,
				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
				      NULL);

  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
    strcpy(fname, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)));
    doLoad = TRUE;
  }

  gtk_widget_destroy (dialog);
#endif

  if (doLoad) {
    open_file(fname);
    have_fname = TRUE;
    setTitle(fname);
  }


}

void save_file(char *filename) {
  FILE *fp;
  int i;

  fp=fopen(filename, "wb");

  // First create dummy header (hangover from when it was on a Psion organiser)
  for (i = 0; i < 16; i++) {
    fputc (0x00, fp);
  }

  // Now write knot size
  fputc((byte)kwidth, fp);  // width byte
  fputc((byte)0x00, fp); 	// zero byte

  fputc((byte)kheight, fp); // height byte
  fputc((byte)0x00, fp); 	// zero byte

  // Now put contents
  for (i = 0; i < (kwidth * kheight); i++) {
     fputc((byte)knot[i], fp);
  }

  fclose(fp);

  drawKnot();
  is_dirty = FALSE;
}

void do_save_as() {
  gboolean doSave = FALSE;

#ifdef G_OS_WIN32
  OPENFILENAME ofn;
  char szFileName[MAX_PATH] = "";
#else
  GtkWidget *dialog;
#endif

#ifdef G_OS_WIN32
  ZeroMemory(&ofn, sizeof(ofn));
  ofn.lStructSize = sizeof(ofn);
  ofn.hwndOwner = NULL;
  ofn.lpstrFilter = "Knot Files (*.knt)\0*.knt\0All Files (*.*)\0*.*\0";
  ofn.lpstrFile = szFileName;
  ofn.nMaxFile = MAX_PATH;
  ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
  ofn.lpstrDefExt = "knt";
  if (GetSaveFileName(&ofn)) {
    doSave = TRUE;
    strcpy(fname, szFileName);
  }
#else
  dialog = gtk_file_chooser_dialog_new ("Save File As",
				      GTK_WINDOW(window),
				      GTK_FILE_CHOOSER_ACTION_SAVE,
				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
				      NULL);

  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
    strcpy(fname, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)));
    doSave = TRUE;
  }

  gtk_widget_destroy (dialog);
#endif

  if (doSave) {
    save_file (fname);
    have_fname = TRUE;
    setTitle(fname);
  }

}

void do_save() {
  if (have_fname) {
    save_file(fname);
  }
  else {
    do_save_as();
  }
}
